package xdu.lz.stage4_atomic.chapter3_atomicReference;

/**
 *
 如果使用普通的对象引用，在多线程情况下进行对象的更新可能会导致不一致性。例如：
 一个对象的初始状态为 name=Tom, age = 18。
 在 线程1 中将 name 修改为 Tom1，age + 1。
 在 线程2 中将 name 修改为 Tom2，age + 2。

 我们认为只会产生两种结果：

 若 线程1 先执行，线程2 后执行，则中间状态为 name=Tom1, age = 19，结果状态为 name=Tom2, age = 21
 若 线程2 先执行，线程1 后执行，则中间状态为 name=Tom2, age = 20，结果状态为 name=Tom1, age = 21

 但是可能的输出如下：

 Person is Person(name=Tom, age=18)
 Thread1 Values Person(name=Tom2, age=21)
 Thread2 Values Person(name=Tom2, age=21)
 Now Person is Person(name=Tom2, age=21)

  thread2把age = 18改为age = 20，
 然后thread1把age+1 = 21，名字改为tom1.
 thread2此时又把名字改为tom2.

 也就是说更新Person的信息的单个【如更新年龄】不是原子，整体【更新p1】也不是原子，导致这样。
 可以用的做法是把Person所有的成员更新都用原子 ，但是整体仍不是原子。
 */
public class Test1 {
    private static Person person;

    static class Task1 implements Runnable {
        public void run() {

            //整个对象的成员更新也不是原子
            person.setAge(person.getAge() + 1);
            person.setName("Tom1");

            System.out.println("Thread1 Values "
                    + person.toString());
        }
    }

    static class Task2 implements Runnable {
        public void run() {
            person.setAge(person.getAge() + 2);
            person.setName("Tom2");

            System.out.println("Thread2 Values "
                    + person.toString());
        }
    }
    public static void main(String[] args) throws InterruptedException {
        person = new Person("Tom", 18);

        System.out.println("Person is " + person.toString());

        Thread t1 = new Thread(new Task1());
        Thread t2 = new Thread(new Task2());

        t1.start();
        t2.start();

        t1.join();
        t2.join();

        System.out.println("Now Person is " + person.toString());
    }


}
